#include "server.h"

int	main(int	argc,
	     char	**argv)
{
  int			sfd = 0;
  struct sockaddr_in	ssock;
  struct sockaddr_in	copy;
  struct ip_mreq	mreq;
  char			buff[BUFFSIZE] = {0};
  char			*cmp = NULL;
  char			*new_mess = NULL;
  char			*file = NULL;
  FILE			*f;
  int			len = 0;
  int			port;
  int			i = 1;

  if (argc < 2)
    printf("Arguments missing !\n");
  else
    {
      cmp = malloc(3 * sizeof(char));
      new_mess = malloc(20 * sizeof(char));
      file = malloc(50 * sizeof(char));
      sfd = create_socket();
      port = atoi(argv[1]);
      if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) < 0)
	{
	  perror("Reusing ADDR failed");
	  return 1;
	}

      memset(&ssock, 0, sizeof(ssock));
      init_socket(sfd, ssock, port);
      join_multicast(sfd, mreq);
      len = sizeof(ssock);

      while (1)
	{
	  /* listen */
	  if ((recvfrom(sfd, buff, BUFFSIZE, 0, (struct sockaddr *) &ssock, &len)) < 0)
	    {
	      perror("recvfrom error");
	      return (1);
	    }
	  printf(buff);
	  cmp = strncpy(cmp, buff, 2);
	  if (strcmp(cmp, "20") == 0)
	    {
	      new_mess = strcat(new_mess, "30");
	      new_mess = strcat(new_mess, get_ip());
	      copy.sin_addr.s_addr = inet_addr(extract(buff, 2, strlen(buff)));
	      copy.sin_family = AF_INET;
	      copy.sin_port = ssock.sin_port;

	      if (sendto(sfd, new_mess, strlen(new_mess), 0, (struct sockaddr *) &copy,
			 sizeof(copy)) < 0)
		{
		  perror("sendto2");
		  return 1;
		}
	    }

	  if (strcmp(cmp, "10") == 0)
	    {
	      extract_header(buff);
	      file = extract_fheader(buff);
	      f = fopen(file, "w");
	      if (f == NULL)
		{
		  perror("fopen()");
		  exit(errno);
		}
	      while (strcmp(buff, "-1\0") != 0)
		{
		  fwrite(buff + 1, 1, strlen(buff), f); //strlen(buff) ne marchera pas avec binaire
		  memset(buff, '\0', sizeof(buff));
		  if (recvfrom(sfd, buff, sizeof(buff), 0, (struct sockaddr *) &ssock,
			       &len) < 0)
		    {
		      perror("recvfrom()");
		      exit(errno);
		    }
		}
	      send_file(file, sfd, ssock, len);

	    }

	  /* print recvform */
	  /* write(1, buff, strlen(buff)); */
	  
	  /* response to an ip_request */
	  /*if (buff[0] == '2')
	    {
	    need_ip(buff, sfd, port);
	    }*/
	  sleep(1);
	}
    }
  return 0;
}

int	create_socket(void)
{
  int	sfd = 0;

  if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
  {
    perror("socket error");
    return (1);
  }

  return sfd;
}

void	init_socket(int sfd, struct sockaddr_in ssock, int port)
{
  ssock.sin_family = AF_INET;
  ssock.sin_addr.s_addr = htonl(INADDR_ANY);
  ssock.sin_port = htons(port);

  if (bind(sfd, (struct sockaddr *) &ssock, sizeof(ssock)) < 0)
  {
    perror("bind error");
    return;
  }
}

int	join_multicast(int sfd, struct ip_mreq mreq)
{
  mreq.imr_multiaddr.s_addr = inet_addr(get_groupip(get_ip()));
  mreq.imr_interface.s_addr = htonl(INADDR_ANY);

  if (setsockopt(sfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
  {
    perror("setsockopt error");
    return (1);
  }

  return 0;
}

char	*extract(char *s, int start, int end)
{
  char	*new = NULL;
  int	i;

  if ((s != NULL) && (start < end))
    {
      new = malloc(sizeof(new) * (end - start + 2));
      if (new != NULL)
	{
	  for (i = start; i <= end; i++)
	    new[i - start] = s[i];
	  new[i - start] = '\0';
	}
    }

  return new;
}

int	need_ip(char	*buff, int	sfd, int	port)
{
  char	*msg;
  char	*resp;
  int	res = 0;
  int	i = 0;
  int	j = 0;
  struct sockaddr_in ssock;

  resp = malloc(16 * sizeof(char));
  msg = malloc (18 * sizeof(char));
  msg = strcat(msg, "30");
  msg = strcat(msg, (char *)get_ip());

  for (i = 2; ((buff[i] != '\0') && i < (strlen (msg))); i++)
    {
      resp[j] = buff[i];
      j++;
    }

  memset(&ssock, 0, sizeof(ssock));
  ssock.sin_family = AF_INET;
  ssock.sin_addr.s_addr = inet_addr(resp);
  ssock.sin_port = htons(port);

  printf ("\n socket %i\n", sfd);
  printf ("\n msg %s\n", msg);
  printf ("\n %s\n", resp);
  printf ("\n port %i\n", port);

  res = sendto(sfd, msg, strlen(msg), 0, (struct sockaddr*) &ssock, sizeof(ssock));

  printf ("\n res %i\n", res);

  if (res < 0)
    {
      perror("sendto error ip_addr");
      return (1);
    }
  return res;
}
